package com.cash.channel.web.controller;

import com.alibaba.fastjson.JSON;
import com.cash.channel.web.annotation.ServiceLog;
import com.cash.channel.api.constant.Constant;
import com.cash.channel.api.exception.CashChannelException;
import com.cash.channel.api.model.ApiRequestModel;
import com.cash.channel.api.model.ApiResponseModel;
import com.cash.channel.api.model.channel.ChannelModel;
import com.cash.channel.api.service.ApiService;
import com.cash.channel.web.model.ParamsChecker;
import com.cash.channel.web.model.RequestModel;
import com.cash.channel.web.signature.AESTool;
import com.cash.channel.web.signature.SignatureTool;
import com.cash.common.model.CodeEnum;
import com.cash.common.model.Result;
import lombok.extern.slf4j.Slf4j;

import javax.annotation.Resource;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

@Slf4j
public class BaseController {

    @Resource
    private ApiService cashChannelApiService;

    protected ApiResponseModel callChannelApi(String key, String data, ChannelModel channelModel, ParamsChecker paramsChecker) throws CashChannelException {
        paramsChecker.doParamsCheck(JSON.parseObject(data).getInnerMap());
        ApiRequestModel apiRequestModel = new ApiRequestModel(key, data, channelModel.getcChannel(), 0 == channelModel.getnCustom()? Constant.CHANNEL.COMMON: channelModel.getcChannel());
        log.info("@@@调用["+apiRequestModel.getKey()+"]");
        log.info("@@@入参:"+ apiRequestModel.getData());
        ApiResponseModel responseModel = cashChannelApiService.api(apiRequestModel);
        log.info("@@@调用["+apiRequestModel.getKey()+"]返回");
        log.info("@@@出参:"+ JSON.toJSONString(responseModel));
        return responseModel;
    }

    protected RequestModel checkSignAndEncrypt(RequestModel requestModel) throws CashChannelException {
        Result<ChannelModel> channelModelResult = cashChannelApiService.getChannelInfoByChannelId(requestModel.getChannel());
        if (CodeEnum.ERROR.getCode().equals(channelModelResult.getCode())) {
            log.error("查询渠道["+requestModel.getChannel()+"]信息失败："+channelModelResult.getMsg());
            throw new CashChannelException("查询渠道["+requestModel.getChannel()+"]信息失败");
        }
        ChannelModel channelModel = channelModelResult.getData();
        SignatureTool.checkSign(requestModel, channelModel.getcChannelPublicKey());
        return requestModel;
    }

    @ServiceLog("调用统一转发方法")
    protected Result doDispatch(String apiName, RequestModel requestModel, ParamsChecker paramsChecker) throws CashChannelException {
        try {
            this.checkSignAndEncrypt(requestModel);
            Result<ChannelModel> channelModelResult = cashChannelApiService.getChannelInfoByChannelId(requestModel.getChannel());
            if (CodeEnum.ERROR.getCode().equals(channelModelResult.getCode())) {
                log.error("查询渠道["+requestModel.getChannel()+"]信息失败："+channelModelResult.getMsg());
                throw new CashChannelException("查询渠道["+requestModel.getChannel()+"]信息失败");
            }
            ChannelModel channelModel = channelModelResult.getData();
            ApiResponseModel apiResponseModel = callChannelApi(apiName, requestModel.getData(), channelModel, paramsChecker);
            if (!apiResponseModel.getSuccess()) {
                return Result.failed(apiResponseModel.getMessage());
            }
            return Result.succeed(Base64.getEncoder().encodeToString(
                    AESTool.aesEncrypt(JSON.toJSONString(apiResponseModel.getResult()).getBytes(StandardCharsets.UTF_8)
                            , channelModel.getcPlatformAesKey())), "");
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new CashChannelException(e.getMessage());
        }
    }

}
